home *** CD-ROM | disk | FTP | other *** search
/ PCMania 48 / PCMania CD48_1.iso / pcmania / mod48 / pcx3.c < prev   
C/C++ Source or Header  |  1994-07-08  |  5KB  |  281 lines

  1. // Extractor de ficheros PCX. By Esteban Moreno Valdés
  2.  
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <dos.h>
  6. #include <fcntl.h>
  7. #include <process.h>
  8. #include <alloc.h>
  9. #include <io.h>
  10. #include <string.h>
  11. #include "intro.h"
  12.  
  13. BYTE far *fpointer;
  14. BYTE far *st;
  15. BYTE fichero[30],paleta[769];
  16. WORD MAXX,MAXY;
  17.  
  18. struct {
  19.     WORD size;
  20.     BYTE test;
  21.     BYTE encoding;
  22.     WORD x1,y1,x2,y2;
  23.     WORD HR,VR;
  24.     WORD bpl;
  25.     BYTE planes;
  26.     BYTE paleta;
  27. } PCX;
  28.  
  29. void apunta_ES(void);
  30. void load_pcx(char nombre[]);
  31. void set_video_mode(BYTE);
  32. void put_image(void);
  33. void cargar_paleta(void);
  34. void get_data(void);
  35. void enciende(void);                // Enciende la paleta
  36. void apaga(void);                   // Oscurece la paleta
  37. void desactiva(void);               // Pone todos los colores a 0
  38. BYTE get_pixel(WORD,WORD);
  39. void put_pixel(WORD,WORD,BYTE);     // Pone un pixel en pantalla
  40.  
  41. WORD code(BYTE,BYTE);               // Invierte el orden de dos bytes
  42.                     // en un mismo Word
  43. void load_pcx(char nombre[])
  44. {
  45.     int handle;
  46.     unsigned bytes_read;
  47.  
  48.     // Carga un PCX
  49.  
  50.     if ( (_dos_open(nombre,O_RDONLY,&handle))!=0 ) {
  51.         printf("\nError : No se puede cargar el fichero especificado\n\n");
  52.         exit(0);
  53.     }
  54.  
  55.     // Asigna memoria
  56.  
  57.     PCX.size = (WORD)filelength(handle);
  58.  
  59.     if ( (fpointer = (BYTE far *) farmalloc(PCX.size+2)) == NULL ) {
  60.         set_video_mode(0x3);
  61.         printf("\nError : No se puede asignar memoria correctamente.\n\n");
  62.         exit(0);
  63.     }
  64.  
  65.     // Lee la imagen entera y la almacena en un puntero
  66.  
  67.     _dos_read(handle,(BYTE far *) fpointer,PCX.size,&bytes_read);
  68.  
  69.     // Cierra el fichero PCX
  70.  
  71.     _dos_close(handle);
  72.  
  73.     get_data();
  74.     desactiva();
  75.     put_image();
  76.     cargar_paleta();
  77.     farfree(fpointer);
  78. }
  79.  
  80. void set_video_mode(BYTE modo)
  81. {
  82.     asm {
  83.         xor    ah,ah
  84.         mov    al,modo
  85.         int    10h
  86.     }
  87. }
  88.  
  89. void apunta_ES(void)
  90. {
  91.     asm {
  92.         mov    ax,0a000h
  93.         mov    es,ax
  94.     }
  95. }
  96.  
  97. void put_image(void)
  98. {
  99.     BYTE get_byte,sb,i,i2,color;
  100.     WORD pdi=0,X=0,Y=0;
  101.  
  102.     MAXX = PCX.x2 - PCX.x1 +1;
  103.     MAXY = PCX.y2 - PCX.y1 +1;
  104.  
  105.     st=fpointer;                // Guardo la dirección del puntero
  106.     fpointer+=128;              // Un vez leída me salto la cabecera
  107.  
  108.     while (Y <= MAXY) {
  109.  
  110.     get_byte=*fpointer;         // Cojo un byte
  111.     sb = get_byte & 192;
  112.  
  113.     if (sb==192)  { i = get_byte & 63;   // Nº de veces que se repetirá
  114.  
  115.                          // el siguiente byte de la Img.
  116.               fpointer++;
  117.               color = *fpointer;
  118.               apunta_ES();
  119.               for (i2=1;i2<=i;i2++) {
  120.                 pdi = (320 * Y) + X;
  121.                 asm     mov    di,pdi
  122.                 asm     mov    al,color
  123.                 asm    mov    es:[di],al
  124.                 X++;
  125.                 if (X >= MAXX) { X=0; Y++; }
  126.               }
  127.               fpointer++;             // Next byte
  128.     }
  129.  
  130.     else {        color = *fpointer;
  131.  
  132.               apunta_ES();
  133.               pdi = (320 * Y) + X;
  134.               asm    mov    di,pdi
  135.               asm    mov    al,color
  136.               asm    mov    es:[di],al
  137.               X++;
  138.  
  139.               if (X >= MAXX) { X=0; Y++; }
  140.  
  141.               fpointer++;             // Next byte
  142.     }
  143.     }
  144.     fpointer=st;          // Recupero la antigua dirección del puntero
  145. }
  146.  
  147. WORD code(BYTE lbyte,BYTE hbyte)
  148. {
  149.     union REGS regs;
  150.  
  151.     regs.h.al=*(fpointer+lbyte);
  152.     regs.h.ah=*(fpointer+hbyte);
  153.     return( regs.x.ax );
  154. }
  155.  
  156. void cargar_paleta(void)
  157. {
  158.     WORD index,adr=0;
  159.  
  160.     fpointer=fpointer+(PCX.size-768);
  161.  
  162.     for (index=0;index<=255;index++) {
  163.         *(fpointer+adr)=*(fpointer+adr)/4; adr++;
  164.         *(fpointer+adr)=*(fpointer+adr)/4; adr++;
  165.         *(fpointer+adr)=*(fpointer+adr)/4; adr++;
  166.     }
  167. }
  168.  
  169. void desactiva(void)
  170. {
  171.     WORD index;
  172.  
  173.     for (index=0;index<=255;index++) {
  174.         outportb(0x3C8,index);
  175.         outportb(0x3C9,0);
  176.         outportb(0x3C9,0);
  177.         outportb(0x3C9,0);
  178.     }
  179. }
  180.  
  181. void enciende(void)
  182. {
  183.     BYTE r,g,b,r2,g2,b2;
  184.     WORD index,index2,adr=0;
  185.  
  186.     for (index2=0;index2<=63;index2++) {
  187.  
  188.         for (index=0;index<=255;index++) {
  189.             outportb(0x3C7,index);
  190.             r=inportb(0x3C9);
  191.             g=inportb(0x3C9);
  192.             b=inportb(0x3C9);
  193.             r2=*(fpointer+adr); adr++;
  194.             g2=*(fpointer+adr); adr++;
  195.             b2=*(fpointer+adr); adr++;
  196.             if (r<r2) r++;
  197.             if (g<g2) g++;
  198.             if (b<b2) b++;
  199.             outportb(0x3C8,index);
  200.             outportb(0x3C9,r);
  201.             outportb(0x3C9,g);
  202.             outportb(0x3C9,b);
  203.         }
  204.             adr=0;
  205.     }
  206. }
  207.  
  208. void apaga(void)
  209. {
  210.     BYTE r,g,b;
  211.     WORD index,index2,adr=0;
  212.  
  213.     for (index2=0;index2<=63;index2++) {
  214.  
  215.         for (index=0;index<=255;index++) {
  216.             outportb(0x3C7,index);
  217.             r=inportb(0x3C9);
  218.             g=inportb(0x3C9);
  219.             b=inportb(0x3C9);
  220.             if (r>0) r--;
  221.             if (g>0) g--;
  222.             if (b>0) b--;
  223.             outportb(0x3C8,index);
  224.             outportb(0x3C9,r);
  225.             outportb(0x3C9,g);
  226.             outportb(0x3C9,b);
  227.         }
  228.     }
  229. }
  230.  
  231. void get_data(void)
  232. {
  233.     PCX.test     = *(fpointer);
  234.     PCX.encoding = *(fpointer+2);
  235.     PCX.planes   = *(fpointer+65);
  236.     PCX.paleta   = *(fpointer+(PCX.size-769));
  237.     PCX.HR       = code(12,13);
  238.     PCX.VR       = code(14,15);
  239.     PCX.x1       = code(4,5);
  240.     PCX.y1       = code(6,7);
  241.     PCX.x2       = code(8,9);
  242.     PCX.y2       = code(10,11);
  243.     PCX.bpl      = code(66,67);
  244. }
  245.  
  246. void put_pixel(WORD x,WORD y,BYTE color)
  247. {
  248.     asm {
  249.         mov    ax,y
  250.         mov    bx,y
  251.         shl    ax,8
  252.         shl     bx,6
  253.         add    ax,bx       // Y * 320
  254.         mov    di,x
  255.         add    di,ax       // Y * 320 + X
  256.         mov    ax,0a000h
  257.         mov    es,ax
  258.         mov    al,color
  259.         mov    es:[di],al
  260.     }
  261. }
  262.  
  263. BYTE get_pixel(WORD x,WORD y)
  264. {
  265.     BYTE color;
  266.  
  267.     asm {
  268.         mov    ax,y
  269.         mov    bx,y
  270.         shl    ax,8
  271.         shl     bx,6
  272.         add    ax,bx       // Y * 320
  273.         mov    di,x
  274.         add    di,ax       // Y * 320 + X
  275.         mov    ax,0a000h
  276.         mov    es,ax
  277.         mov    al,es:[di]
  278.         mov    color,al
  279.     }
  280.         return(color);
  281. }